﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Xml.Linq;
using DevWeb.Biztalk.DeploymentSettings.DeploymentService.Contracts;
using DevWeb.Biztalk.DeploymentSettings.DeploymentService.Contracts.Model;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace DevWeb.BizTalk.DeploymentFramework.Tasks
{
    public class GetEnvironmentSettingsTasks : Task
    {
        [Required]
        public string ProjectName { get; set; }

        [Required]
        public string ProductId { get; set; }

        [Required]
        public string ProductUpgradeCode { get; set; }

        [Required]
        public string Version { get; set; }

        [Required]
        public string SettingFilePath { get; set; }

        [Required]
        public string ServiceAddress { get; set; }


        private string _environment = string.Empty;

        public override bool Execute()
        {



            FileInfo fi = new FileInfo(SettingFilePath);

            if (fi.Directory != null && !fi.Directory.Exists)
            {
                fi.Directory.Create();
                
            }
            if (!fi.Exists)
            {
                using (var fs= fi.Create())
                {
                    fs.Flush();
                    
                }
                
            }
           
                
                
            string logmsg =
                string.Format(
                    "User {4} called GetEnvironmentSettingsTasks for integration {0} with version : {1} (ProductId:{2}) (ProductUpgradeCode{3}) on date: {5}",
                    ProjectName, Version, ProductId, ProductUpgradeCode, Environment.UserName, DateTime.Now.ToString(CultureInfo.InvariantCulture));
            

          Log.LogMessage(MessageImportance.High,logmsg );

            var settings = GetSettings();
            var settingcount = settings.ExportParameters.Count;

           Log.LogMessage(MessageImportance.High, string.Format("Found {0} settings for this integration ", settingcount));
            WriteXmlFile(SettingFilePath, settings, ProductId, ProductUpgradeCode, ProjectName, logmsg);

            return true;
        }

        private void WriteXmlFile(string settingsfilepath, ExportModel settings, string ProductId, string ProductUpgradeCode, string ProjectName, string header)
        {




            var doc = new XDocument(new XComment(header));

            
            var rootElement = new XElement("settings");

            foreach (var integrationVersionSettingItem in settings.ExportParameters)
            {
                var itemElement = new XElement("property", new XAttribute("name", integrationVersionSettingItem.ParameterName), GetSettingValue(integrationVersionSettingItem));
                if (integrationVersionSettingItem.IsDefaultValue)
                {
                    itemElement.Add(new XAttribute("Default","true"));
                }
                rootElement.Add(itemElement);
            }

            doc.Add(rootElement);

           doc.Save(settingsfilepath);
           Log.LogMessage(MessageImportance.High, string.Format("Settings saved  to {0} settings for this integration ",SettingFilePath));
        
        }

        private string GetSettingValue(ExportParameter parameter)
        {
            var item = parameter.ParameterValues.SingleOrDefault(p => p.Environment.Equals(_environment));
            
            string result = ((item == null)||string.IsNullOrEmpty(item.Value) )? parameter.DefaultValue : item.Value;
            


          

            return result;
        }

        private ExportModel GetSettings()
        {
          Log.LogMessage(MessageImportance.High, string.Format("Setup Client   to {0}  ", ServiceAddress));
           
            try
            {
                var binding = new WSHttpBinding();
                binding.Security.Mode = SecurityMode.None;
                var endpointaddress = new EndpointAddress(ServiceAddress.Trim());

                 var client = ChannelFactory<IDeploymentSettingsService>.CreateChannel(binding, endpointaddress);
                
              
                var productupgragdecode = Guid.Parse(ProductUpgradeCode);
                var productid = Guid.Parse(ProductId);
                _environment = Environment.GetEnvironmentVariable("BTDFENV");
                var settings = client.GetEnvironmentSettings(productupgragdecode, productid, _environment);
                return settings;
            }
            catch (Exception ex)
            {

          Log.LogMessage(MessageImportance.High, string.Format("Client Failed cause {0} - StackTrace: {1} ", ex.ToString(), ex.StackTrace));
            }
            return null;
        }

        
    }
}
